package cn.qidd.keep.manage.service.login.impl;

import cn.qidd.keep.domain.core.Constants;
import cn.qidd.keep.domain.core.dict.ResourceType;
import cn.qidd.keep.domain.document.Resource;
import cn.qidd.keep.domain.document.User;
import cn.qidd.keep.domain.web.TokenException;
import cn.qidd.keep.domain.web.UserVO;
import cn.qidd.keep.manage.model.login.LoginModel;
import cn.qidd.keep.manage.model.login.UserInfo;
import cn.qidd.keep.manage.repository.ResourceRepository;
import cn.qidd.keep.manage.service.login.LoginService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Created by sunyanping on 2018/9/13
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ResourceRepository resourceRepository;

    @Override
    public LoginModel login(User user) {

        // 生成token
        String token = generateToken(user.getId());

        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        UserInfo userInfo = new UserInfo();
        userInfo.setUser(userVO);
        List<Resource> all = resourceRepository.findAll();
        userInfo.setMenu(all);
        userInfo.setResource(all.stream().filter(e-> e.getType() != ResourceType.A_MENU).collect(Collectors.toList()));

        LoginModel loginModel = new LoginModel();
        loginModel.setUserInfo(userInfo);
        loginModel.setToken(token);

        // token作为key缓存user
        cacheUser(token, userVO);
        return loginModel;
    }

    /**
     * 生成token
     * @param userId
     * @return
     */
    private String generateToken(String userId) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return String.format("%s%s%s", userId, "_", uuid);
    }

    /**
     * 缓存user信息
     * @param token
     * @param user
     */
    private void cacheUser(String token, UserVO user) {
        stringRedisTemplate.opsForValue().set(token, JSONObject.toJSONString(user), Constants.TOKEN_EXPIRED_TIME, TimeUnit.MINUTES );
    }

    @Override
    public LoginModel getUserInfoByToken(String token) {
        if (StringUtils.isBlank(token)) throw new TokenException();
        Boolean expire = stringRedisTemplate.expire(token, Constants.TOKEN_EXPIRED_TIME, TimeUnit.MINUTES);
        if (expire == null || !expire) throw new TokenException();

        UserVO user = JSONObject.parseObject(stringRedisTemplate.opsForValue().get(token), UserVO.class);
        UserInfo userInfo = new UserInfo();
        userInfo.setUser(user);
        List<Resource> all = resourceRepository.findAll();
        userInfo.setMenu(all);
        userInfo.setResource(all.stream().filter(e-> e.getType() != ResourceType.A_MENU).collect(Collectors.toList()));

        LoginModel loginModel = new LoginModel();
        loginModel.setToken(token);
        loginModel.setUserInfo(userInfo);
        return loginModel;
    }

    @Override
    public void logout(String token) {
         stringRedisTemplate.delete(token);
    }
}
